package com.zhuanzhuan.hero.user.converter;

import com.zhuanzhuan.hero.user.consts.Consts;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.entity.HeroLabelInfo;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.enums.LabelCodeEnum;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.pojo.po.LabelInfoPO;
import com.zhuanzhuan.hero.user.util.Assert;
import com.zhuanzhuan.hero.user.vo.label.LevelLabelVO;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName LabelUtil
 * @Description
 * @Author hanjunjun
 * @Date 2024/6/26 16:54
 */
public class LabelConverter {

    /**
     * 平铺的构建为层级结构
     *
     * @param labelInfos
     * @return java.util.List<com.zhuanzhuan.hero.user.vo.label.LevelLabelVO>
     * @author  hanjunjun
     * @date 2024/6/26
     **/
    public static List<LevelLabelVO> buildLevelLabel(List<HeroLabelInfo> labelInfos) {
        List<LevelLabelVO> resultList = new ArrayList<>();

        //根据level分组
        Map<Integer, List<HeroLabelInfo>> levelMap =
            labelInfos.stream().collect(Collectors.groupingBy(HeroLabelInfo::getLabelLevel));

        //层级最小值
        List<HeroLabelInfo> firstLevelLabels = levelMap.get(levelMap.keySet().stream().min(Integer::compareTo).orElse(NumConsts.ONE));
        //装配第一级
        for (HeroLabelInfo firstLevelLabel : firstLevelLabels) {
            LevelLabelVO labelVo = convertLevelLabelVO(firstLevelLabel);
            resultList.add(labelVo);
        }

        //根据parentCode分组
        Map<String, List<HeroLabelInfo>> parentCodeMap =
            labelInfos.stream().collect(Collectors.groupingBy(HeroLabelInfo::getParentLabelCode));
        //遍历第一级，装配下级
        resultList.forEach(labelVo -> recursionBuildChildLabel(labelVo, parentCodeMap));

        return resultList;
    }

    private static void recursionBuildChildLabel(LevelLabelVO levelLabelVO, Map<String, List<HeroLabelInfo>> parentCodeMap) {
        if (Objects.isNull(levelLabelVO)) {
            return;
        }
        List<HeroLabelInfo> childs = parentCodeMap.get(levelLabelVO.getLabelCode());
        if (CollectionUtils.isNotEmpty(childs)) {
            levelLabelVO.setHasChilds(true);
            List<LevelLabelVO> childList = convertLabelVoList(childs);
            levelLabelVO.setChildLabels(childList);
            childList.forEach(child -> recursionBuildChildLabel(child, parentCodeMap));
        }
    }

    private static List<LevelLabelVO> convertLabelVoList(List<HeroLabelInfo> infoList) {
        return infoList.stream().map(LabelConverter::convertLevelLabelVO)
            .sorted(Comparator.comparingInt(LevelLabelVO::getShowOrder))
            .collect(Collectors.toList());
    }

    public static LevelLabelVO convertLevelLabelVO(HeroLabelInfo heroLabelInfo) {
        LevelLabelVO levelLabelVO = new LevelLabelVO();
        levelLabelVO.setLabelId(heroLabelInfo.getId());
        levelLabelVO.setLabelCode(heroLabelInfo.getLabelCode());
        //如果labelValue为空则赋一个labelId  只有盘古品牌、机型有labelValue
        levelLabelVO.setLabelValue(heroLabelInfo.getId().intValue());
        levelLabelVO.setLabelName(heroLabelInfo.getLabelName());
        levelLabelVO.setLabelLevel(heroLabelInfo.getLabelLevel());
        levelLabelVO.setParentLabelCode(heroLabelInfo.getParentLabelCode());
        levelLabelVO.setShowOrder(Objects.isNull(heroLabelInfo.getShowOrder()) ? NumConsts.ONE : heroLabelInfo.getShowOrder());
        return levelLabelVO;
    }

    /**
     * 层级结构平铺开
     *
     * @param levelLabelList
     * @return void
     * @author  hanjunjun
     * @date 2024/6/26
     **/
    public static List<LevelLabelVO> flatLevel(List<LevelLabelVO> levelLabelList) {
        List<LevelLabelVO> flatList = new ArrayList<>();
        recursionFlat(levelLabelList, flatList);
        return flatList;
    }

    private static void recursionFlat(List<LevelLabelVO> childList, List<LevelLabelVO> flatList) {
        if (CollectionUtils.isEmpty(childList)) {
            return;
        }
        childList.forEach(levelLabel -> {
            flatList.add(levelLabel);
            recursionFlat(levelLabel.getChildLabels(), flatList);
        });
    }

    /**
     * 查询标签的顶级父标签
     *
     * @param labelId
     * @param labelInfos
     * @return com.zhuanzhuan.hero.user.entity.HeroLabelInfo
     * @author  hanjunjun
     * @date 2024/7/8
     **/
    public static HeroLabelInfo findTopLevelByLastLevel(Long labelId, List<HeroLabelInfo> labelInfos) {
        HeroLabelInfo theLabelInfo =
            labelInfos.stream().filter(label -> label.getId().equals(labelId)).findFirst().orElse(null);
        if (Objects.isNull(theLabelInfo)) {
            return null;
        }

        return recursionFindFirstLevel(theLabelInfo, labelInfos);
    }

    /**
     * 寻找【主营品类】下的子标签
     *
     * @param relatedManagementlabelInfos
     * @param managementLabelInfos 所有的经营标签
     * @return java.util.List<com.zhuanzhuan.hero.user.pojo.po.LabelInfoPO>
     * @author  hanjunjun
     * @date 2024/7/11
     **/
    public static List<LabelInfoPO> findBusinessCateChilds(List<LabelInfoPO> relatedManagementlabelInfos,
        List<HeroLabelInfo> managementLabelInfos) {
        if (CollectionUtils.isEmpty(relatedManagementlabelInfos)) {
            return new ArrayList<>();
        }

        return relatedManagementlabelInfos.stream()
            //顶级父标签是【主营品类】的
            .filter(label -> {
                HeroLabelInfo topLevelLabel =
                    LabelConverter.findTopLevelByLastLevel(label.getLabelId(), managementLabelInfos);
                Assert.notNull(topLevelLabel, ExceptionMsgEnum.BUSINESS_ERROR);
                return LabelCodeEnum.FIRST_MANAGEMENT_CATE.getCode().equals(topLevelLabel.getLabelCode());
            })
            .collect(Collectors.toList());
    }


    /**
     * 递归查找最上层的label
     *
     * @param labelInfo
     * @param labelInfos
     * @return com.zhuanzhuan.hero.user.entity.HeroLabelInfo
     * @author  hanjunjun
     * @date 2024/7/8
     **/
    private static HeroLabelInfo recursionFindFirstLevel(HeroLabelInfo labelInfo, List<HeroLabelInfo> labelInfos) {
        String parentLabelCode = labelInfo.getParentLabelCode();
        if (Consts.FIRST_LEVEL_PARENT_DEFAULT_CODE.equals(parentLabelCode)) {
            return labelInfo;
        }
        HeroLabelInfo parentLabel =
            labelInfos.stream().filter(label -> label.getLabelCode().equals(parentLabelCode))
                .findFirst().orElseThrow(() -> new BusinessException(ExceptionMsgEnum.BUSINESS_ERROR));
        return recursionFindFirstLevel(parentLabel, labelInfos);
    }

}
